import { useControllableValue } from 'ahooks'
import { FocusEvent, forwardRef, memo } from 'react'
import { InputNumber } from 'antd'

type CurrencyValue = number | string | undefined

interface LuckyCurrencyInputProps {
  /**
   * @description 值
   * @default ''
   */
  value?: CurrencyValue
  /**
   * @description 默认值
   * @default ''
   */
  defaultValue?: CurrencyValue
  /**
   * @description 小数位
   * @default 2
   */
  precision?: number
  /**
   * @description 占位符
   * @default 请输入
   */
  placeholder?: string
  /**
   * @description 最小值
   * @default 0
   */
  min?: number
  /**
   * @description 最大值
   * @default Infinity
   */
  max?: number
  /**
   * @description 模式
   * @default write
   */
  mode?: 'read' | 'write'
  disabled?: boolean
  /**
   * @description 是否自动聚焦
   * @default false
   */
  autoFocus?: boolean
  onChange?: (value: CurrencyValue) => void
  onBlur?: (e: FocusEvent) => void
  onFocus?: (e: FocusEvent) => void
}

const LuckyCurrencyInput = forwardRef<HTMLDivElement, LuckyCurrencyInputProps>((props, ref) => {
  const { min = 0, max = Infinity, defaultValue = '', autoFocus = false, placeholder = '请输入', precision = 2, mode = 'write', onFocus, onBlur } = props

  // 受控/非受控状态
  const [inputValue, setInputValue] = useControllableValue<CurrencyValue>(props, { defaultValue })

  const handleValueFormat = (val: string | number | undefined) => {
    /**
     * 切割整数位和小数位
     * 对整数位进行格式化
     * eg: 1000 -> 1,000
     */
    const [integerPart, decimalPart] = String(val).split('.')
    const formattedInteger = `${String(integerPart).replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, '$1,')}`
    return decimalPart !== undefined ? `${formattedInteger}.${decimalPart}` : formattedInteger
  }

  const handleValueChange = (val: CurrencyValue) => {
    setInputValue(val)
  }

  const handleFocus = (e: FocusEvent) => {
    onFocus?.(e)
  }

  const handleBlur = (e: FocusEvent) => {
    onBlur?.(e)
  }

  return (
    <div ref={ref}>
      <InputNumber
        value={inputValue}
        placeholder={placeholder}
        controls={false}
        min={min}
        max={max}
        autoFocus={autoFocus}
        precision={precision}
        readOnly={mode === 'read'}
        className="w-[328px]"
        formatter={val => handleValueFormat(val)}
        onChange={val => handleValueChange(val as string)}
        onFocus={handleFocus}
        onBlur={handleBlur}
      />
    </div>
  )
})

export default memo(LuckyCurrencyInput)
